package com.foreverwin.jzymes.production.inspect.service.impl;

import com.foreverwin.jzymes.common.constant.Constants;
import com.foreverwin.jzymes.common.domain.CarrierBind;
import com.foreverwin.jzymes.common.domain.CarrierScanLog;
import com.foreverwin.jzymes.common.domain.NcData;
import com.foreverwin.jzymes.common.enums.CarrierScanLogEnum;
import com.foreverwin.jzymes.common.mapper.CarrierScanLogMapper;
import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.common.util.BOHandleUtil;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.framework.util.ObjectMapperUtil;
import com.foreverwin.jzymes.production.inspect.domain.InspectAlarmLog;
import com.foreverwin.jzymes.production.inspect.mapper.InspectAlarmLogAdviceMapper;
import com.foreverwin.jzymes.production.inspect.service.IInspectAdviceService;
import com.foreverwin.jzymes.production.inspect.service.IInspectAlarmLogService;
import com.foreverwin.jzymes.production.nc.service.ICarrierNCDisposeAdviceService;
import com.foreverwin.jzymes.production.nc.service.ICarrierNCRecordAdviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;

@Service
public class InspectAdviceServiceImpl implements IInspectAdviceService {
    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IResourceAdviceService resourceAdviceService;
    @Autowired
    ICarrierBindAdviceService carrierBindAdviceService;
    @Autowired
    INCDataAdviceService incDataAdviceService;
    @Autowired
    ICommonService commonService;
    @Autowired
    ISystemRuleAdviceService systemRuleAdviceService;
    @Autowired
    ICarrierNCRecordAdviceService carrierNCRecordAdviceService;
    @Autowired
    ICarrierNCDisposeAdviceService carrierNCDisposeAdviceService;
    @Autowired
    ICustomFieldsAdviceService customFieldsAdviceService;
    @Autowired
    INCCodeAdviceService ncCodeAdviceService;
    @Autowired
    IInspectAlarmLogService inspectAlarmLogService;
    @Autowired
    IProductionShiftService productionShiftService;
    @Autowired
    CarrierScanLogMapper carrierScanLogMapper;
    @Autowired
    InspectAlarmLogAdviceMapper inspectAlarmLogAdviceMapper;

    /**
     * 全检扫码报警检查
     *
     * @param carrierScanLog
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void inspectCarrier( CarrierScanLog carrierScanLog ){

        /**检查字段*/
        checkFieldsForInspect( carrierScanLog );
        carrierScanLog.setCreatedDateTime( new Date());

        /**检查本体绑定状态*/
        List<CarrierBind> carrierBindList = carrierBindAdviceService.existCarrierBindonBind( carrierScanLog.getSite(), carrierScanLog.getCarrier() );

        /**检查本体是否已过站*/
        if( commonService.checkCarrierPassOnOperation( carrierBindList.get(0), carrierScanLog.getOperation() ) ){
            carrierScanLog.setPass( CarrierScanLogEnum.N.name() );
        }else{
            carrierScanLog.setPass( CarrierScanLogEnum.Y.name() );
        }

        /**检查是否存在打开的不良项目*/
        checkOpenNcDataOnInspect( carrierScanLog );

        /**本体过站*/
        commonService.sfcPassByCarrier( carrierScanLog.getSite(),carrierScanLog.getCarrier(), carrierScanLog.getResrce(), carrierScanLog.getCreatedDateTime() );

        /**保存扫码信息*/
        carrierScanLog.setMachineType( carrierBindList.get(0).getMachineType() );
        carrierScanLog.setHandle(BOHandleUtil.buildCarrierScanLogHandle() );
        carrierScanLogMapper.insertCarrierScanLog( carrierScanLog );
    }

    /**
     * 记录全检不良
     *
     * @param jsonMap
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void recordCarrierNC( Map<String,Object> jsonMap ){
        carrierNCRecordAdviceService.recordCarrierNC( jsonMap, true );
    }

    /**
     * 处置全检不良
     *
     * @param jsonMap
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void disposeCarrierNC( Map<String,Object> jsonMap ){
        carrierNCDisposeAdviceService.disposeCarrierNC( jsonMap, true );
    }

    /**
     * 检查全检扫码字段
     *
     * @param carrierScanLog
     */
    public void checkFieldsForInspect( CarrierScanLog carrierScanLog ){
        /**检查站点*/
        siteAdviceService.existSite( carrierScanLog.getSite() );
        /**检查设备*/
        Map<String,Object> resourceMap = resourceAdviceService.existResource( carrierScanLog.getSite(), carrierScanLog.getResrce() );
        /**检查工序*/
        String operation = resourceAdviceService.findOperationByResource( resourceMap );
        carrierScanLog.setOperation( operation );
        /**检查本体*/
        Assert.hasText( carrierScanLog.getCarrier(), I18nUtil.getI18nText( "common.carrierNotBlank" ));
        /**设备扫码发送时间不能为空*/
        Assert.notNull( carrierScanLog.getSendTime(), I18nUtil.getI18nText( "production.clamp.carrierCheckSendTimeNotNull" ));
    }


    /**
     * 检查全检不良拦截报警
     *
     * @param carrierScanLog
     */
    public void checkOpenNcDataOnInspect( CarrierScanLog carrierScanLog ){
        /**检查是否存在全检拦截不良项目，存在则发送报警信息*/
        List<NcData> ncDatas = incDataAdviceService.findOpenNcDataFromDate( carrierScanLog.getSite(), carrierScanLog.getCarrier() );
        if( ncDatas != null && ncDatas.size() > 0 ){

            List<Map<String,String>> ncList = new ArrayList<>();
            for( NcData ncData : ncDatas ){
                Map<String,String> ncMap = new HashMap<>();
                String itemBo = ncData.getItemBo();
                Map<String,Object> ncCodeMap = ncCodeAdviceService.existNCCode( ncData.getSite(), ncData.getNcCode() );
                ncMap.put( "mat", customFieldsAdviceService.findCustomValue( itemBo, Constants.ITEM_CUSTOM_FIELD_ITEM_LABEL ) );
                ncMap.put( "nc", String.format( "[%s]%s", ncData.getNcCode(), ncCodeMap.get( "DESCRIPTION" ) ) );
                ncList.add( ncMap );
            }
            throw BusinessException.build( ObjectMapperUtil.writeValueAsString( ncList ) );
            /*StringBuffer warnMessage = new StringBuffer();
            for( NcData ncData : ncDatas ){
                warnMessage.append( I18nUtil.getI18nText( "production.nc.carrierItemNcNotDispose", new String[]{ ncData.getCarrier(), ncData.getItemBo(), ncData.getNcCode() } ) );
                warnMessage.append( ";" );
            }
            throw BusinessException.build( warnMessage.toString() );*/
        }
    }

    /**
     * 保存全检报警记录
     *
     * @param site
     * @param carrier
     * @param alarmMessage
     */
    public void saveInspectAlarmLog( String site, String carrier, String resrce, String alarmMessage ){
        String operation = resourceAdviceService.findOperationByResource( site, resrce );
        InspectAlarmLog inspectAlarmLog = inspectAlarmLogAdviceMapper.selectInspectAlarmLogByCarrierDate( site, carrier, operation );
        if( inspectAlarmLog != null ){
            inspectAlarmLog.setCreatedDateTime( new Date() );
            inspectAlarmLogService.updateInspectAlarmLog( inspectAlarmLog );
        }else{
            inspectAlarmLog = new InspectAlarmLog();
            inspectAlarmLog.setHandle( BOHandleUtil.buildInspectAlarmLogHandle() );
            inspectAlarmLog.setSite( site );
            inspectAlarmLog.setCarrier( carrier );
            inspectAlarmLog.setOperation( operation );
            inspectAlarmLog.setAlarmMsg( alarmMessage );
            inspectAlarmLog.setDisposition( "N" );
            inspectAlarmLog.setCreatedDateTime( new Date() );
            inspectAlarmLogService.insertInspectAlarmLog( inspectAlarmLog );
        }
    }

    /**
     * 修改全检报警记录
     *
     * @param site
     * @param carrier
     */
    public void updateInspectAlarmLog( String site, String carrier, String resrce ){
        String operation = resourceAdviceService.findOperationByResource( site, resrce );
        InspectAlarmLog inspectAlarmLog = inspectAlarmLogAdviceMapper.selectInspectAlarmLogByCarrierDate( site, carrier, operation );
        if( inspectAlarmLog != null ){
            inspectAlarmLog.setDisposition( "Y" );
            inspectAlarmLog.setUpdatedDateTime( new Date() );
            inspectAlarmLogService.updateInspectAlarmLog( inspectAlarmLog );
        }
    }
}
